package cn.com.taiji.oospub.wechat.common;

import cn.hutool.json.JSONObject;
import cn.hutool.json.XML;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

@Component
public class HisAddressUtil {

    @Value("${his_address_url}")
    private String hisAddressUrl;
    @Value("${searchSpace}")
    private String searchSpace;
    @Value("${get_hc_address_by_his_url}")
    private String getHcAddressByHisUrl;
    @Value("${parentSpace}")
    private String parentSpace;
    @Value("${PROJECT_CODE}")
    private String projectCode;
    @Resource
    private RestTemplate restTemplate;


    public String getHospitalNumberByHisSpaceId(String hisSpaceID) {

        switch (projectCode) {
            case "7004029":
                Document document = DocumentHelper.createDocument();
                Element ROW = document.addElement("MESSAGE").addElement("BODY").addElement("ROWS").addElement("ROW");
                ROW.addElement("DEPT_ID").addText(hisSpaceID.split("&")[0]);
                ROW.addElement("BED_ID").addText(hisSpaceID.split("&")[1]);
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_XML);
                HttpEntity<String> formEntity = new HttpEntity<>(getWsdlStr(document.asXML(), "AMK_003"), headers);
                String resultStr = Objects.requireNonNull(restTemplate.postForObject(hisAddressUrl, formEntity, String.class)).trim();
                try {
                    if (StringUtils.hasText(resultStr)) {
                        String resXml = XML.toJSONObject(resultStr).getJSONObject("soap:Envelope").getJSONObject("soap:Body").getJSONObject("ns2:serviceResponse").getStr("return");
                        JSONObject resJson = XML.toJSONObject(resXml);
                        if ("1".equals(resJson.getJSONObject("MESSAGE").getJSONObject("HEADER").getStr("STATUS")) && StringUtils.hasText(resJson.getJSONObject("MESSAGE").getJSONObject("BODY").getStr("ROWS"))) {
                            return resJson.getJSONObject("MESSAGE").getJSONObject("BODY").getJSONObject("ROWS").getJSONObject("ROW").getStr("ZYH");
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
            default:
                break;
        }
        return "";
    }

    public String getDoctorsOrder(String patientNumber) {
        switch (projectCode) {
            case "7004029":
                try {
                    Document document = DocumentHelper.createDocument();
                    Element ROW = document.addElement("MESSAGE").addElement("BODY").addElement("ROWS").addElement("ROW");
                    ROW.addElement("PATIENT_NO").addText(patientNumber);
                    HttpHeaders headers = new HttpHeaders();
                    headers.setContentType(MediaType.APPLICATION_XML);
                    HttpEntity<String> formEntity = new HttpEntity<>(getWsdlStr(document.asXML(), "AMK_001"), headers);
                    String hisAddress = Objects.requireNonNull(restTemplate.postForObject(hisAddressUrl, formEntity, String.class)).trim();
                    if (StringUtils.hasText(hisAddress)) {
                        String resXml = XML.toJSONObject(hisAddress).getJSONObject("soap:Envelope").getJSONObject("soap:Body").getJSONObject("ns2:serviceResponse").getStr("return");
                        cn.hutool.json.JSONObject resJson = XML.toJSONObject(resXml);
                        if ("1".equals(resJson.getJSONObject("MESSAGE").getJSONObject("HEADER").getStr("STATUS")) && StringUtils.hasText(resJson.getJSONObject("MESSAGE").getJSONObject("BODY").getStr("ROWS"))) {
                            com.alibaba.fastjson.JSONObject hisAddressJsonObject = resJson.getJSONObject("MESSAGE").getJSONObject("BODY").getJSONObject("ROWS").get("ROW", com.alibaba.fastjson.JSONObject.class);
                            if (hisAddressJsonObject != null) {
                                return hisAddressJsonObject.getString("DQYS");
                            }
                        }
                    }
                } catch (Exception e) {
                    return "";
                }
                break;
            default:
                break;
        }
        return "";
    }

    public static String getWsdlStr(String xmlStr, String flow) {
        String wsdlStr = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ws=\"http://ws.sie.com\">\n" +
                "\t<soapenv:Header/>\n" +
                "    <soapenv:Body>\n" +
                "        <ws:service>\n" +
                "            <param>flow=FLOW,app=CY</param>\n" +
                "            <data><![CDATA[XMLDATA]]>\n" +
                "                </data>\n" +
                "            </ws:service>\n" +
                "        </soapenv:Body>\n" +
                "    </soapenv:Envelope>";
        return wsdlStr.replaceAll("XMLDATA", xmlStr).replaceAll("FLOW", flow);
    }

    public static String soapPost(String urlStr, String sendMsg) throws Exception {

        System.out.println(sendMsg);
        StringBuffer returnMsg = new StringBuffer();
        URL url = new URL(urlStr);
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        byte[] buf = sendMsg.getBytes();// 用于存放文件数据的数组
        httpConn.setRequestProperty("Content-Type", "application/soap+xml; charset=utf-8");
        httpConn.setRequestMethod("POST");
        httpConn.setDoOutput(true);
        httpConn.setDoInput(true);
        OutputStream out = httpConn.getOutputStream();
        out.write(buf);
        out.close();
        InputStreamReader is = new InputStreamReader(httpConn.getInputStream(), StandardCharsets.UTF_8);
        BufferedReader in = new BufferedReader(is);
        String inputLine;
        while ((inputLine = in.readLine()) != null) {
            returnMsg.append(inputLine);
        }
        in.close();
        httpConn.disconnect();
        return returnMsg.toString();
    }

    public Model searchSpaceInfo(String code, Model model) {
        MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<>();
        if (code.contains("{")) {
            paramMap.add("code", code);
            paramMap.add("searchType", "1");
            model.addAttribute("architecture", getArchitecture(code, 1));
            String address = restTemplate.postForObject(searchSpace, paramMap, String.class).replace("|", ",").trim();
            if (address.split("#").length > 1) {
                model.addAttribute("address", address.split("#")[0]);
                model.addAttribute("hisSpaceID", address.split("#")[1]);
                model.addAttribute("patientNumber", getHospitalNumberByHisSpaceId(address.split("#")[1]));
            } else {
                model.addAttribute("address", address);
            }
        } else {
            switch (projectCode) {
                case "7004029":
                    //花都
                    Document document = DocumentHelper.createDocument();
                    Element ROW = document.addElement("MESSAGE").addElement("BODY").addElement("ROWS").addElement("ROW");
                    ROW.addElement("PATIENT_NO").addText(code);
                    HttpHeaders headers = new HttpHeaders();
                    headers.setContentType(MediaType.APPLICATION_XML);
                    HttpEntity<String> formEntity = new HttpEntity<>(getWsdlStr(document.asXML(), "AMK_001"), headers);
                    String hisAddress = restTemplate.postForObject(hisAddressUrl, formEntity, String.class).trim();
                    if (StringUtils.hasText(hisAddress)) {
                        String resXml = XML.toJSONObject(hisAddress).getJSONObject("soap:Envelope").getJSONObject("soap:Body").getJSONObject("ns2:serviceResponse").getStr("return");
                        cn.hutool.json.JSONObject resJson = XML.toJSONObject(resXml);
                        if ("1".equals(resJson.getJSONObject("MESSAGE").getJSONObject("HEADER").getStr("STATUS")) && StringUtils.hasText(resJson.getJSONObject("MESSAGE").getJSONObject("BODY").getStr("ROWS"))) {
                            com.alibaba.fastjson.JSONObject hisAddressJsonObject = resJson.getJSONObject("MESSAGE").getJSONObject("BODY").getJSONObject("ROWS").get("ROW", com.alibaba.fastjson.JSONObject.class);
                            if (hisAddressJsonObject != null) {
                                model.addAttribute("name", hisAddressJsonObject.getString("XM"));
                                model.addAttribute("tel", hisAddressJsonObject.getString("LXDH"));
                                model.addAttribute("patientNumber", code);
                                paramMap.put("hisSpaceId", Collections.singletonList(hisAddressJsonObject.getString("BQDM") + "&" + hisAddressJsonObject.getString("CWDM")));
                                model.addAttribute("hisSpaceID", hisAddressJsonObject.getString("BQDM") + "&" + hisAddressJsonObject.getString("CWDM"));
                                String hcAddressStr = restTemplate.postForObject(getHcAddressByHisUrl, paramMap, String.class).trim();
                                List<com.alibaba.fastjson.JSONObject> hcAddressList = com.alibaba.fastjson.JSONObject.parseArray(hcAddressStr, com.alibaba.fastjson.JSONObject.class);
                                if (hcAddressList.size() > 0) {
                                    for (com.alibaba.fastjson.JSONObject hcAddressJson : hcAddressList) {
                                        if ("1".equals(hcAddressJson.getJSONObject("spaceType").getString("id"))) {
                                            model.addAttribute("architecture", hcAddressJson.getString("spaceName"));
                                        } else if ((hcAddressList.size() + "").equals(hcAddressJson.getJSONObject("spaceType").getString("id"))) {
                                            paramMap.clear();
                                            paramMap.add("code", hcAddressJson.getString("spaceCode"));
                                            paramMap.add("searchType", "1");
                                            model.addAttribute("address", restTemplate.postForObject(searchSpace, paramMap, String.class).replace("|", ",").trim().split("#")[0]);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    break;
                default:
                    break;
            }
        }
        return model;
    }

    public String getArchitecture(String spaceCode, int num) {
        while (num < 4) {
            num++;
            MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<>();
            paramMap.add("spaceCode", spaceCode);
            RestTemplate restTemplate = new RestTemplate();
            String s = restTemplate.postForObject(parentSpace, paramMap, String.class);
            com.alibaba.fastjson.JSONObject result = com.alibaba.fastjson.JSONObject.parseObject(s, com.alibaba.fastjson.JSONObject.class);
            if ("1".equals(result.getString("spaceTypeId"))) {
                return result.getString("spaceName");
            } else {
                return getArchitecture(result.getString("spaceCode"), num);
            }
        }
        return "";
    }
}
